﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Text.RegularExpressions;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace Mindfor.Web.Data
{
	/// <summary>
	/// Class for Mail template data object.
	/// </summary>
	public class MailTemplate : IdEntity
	{
		/// <summary>
		/// Gets or sets template language.
		/// </summary>
		[DisplayName("Язык")]
		public virtual Language Language { get; set; }

		/// <summary>
		/// Gets or sets template type.
		/// </summary>
		public virtual MailTemplateType Type { get; set; }

		/// <summary>
		/// Gets or sets subject field template.
		/// </summary>
		[DisplayName("Тема письма")]
		[Required(ErrorMessage = "Введите тему письма")]
		[StringLength(255, ErrorMessage = "Тема должна быть не длиннее 255 символов")]
		public virtual string Subject { get; set; }

		/// <summary>
		/// Gets or sets body field template.
		/// </summary>
		[DisplayName("Текст письма")]
		[Required(ErrorMessage = "Введите текст письма")]
		public virtual string Body { get; set; }

		/// <summary>
		/// Gets or sets wheather body is in HTML format.
		/// </summary>
		[DisplayName("Текст письма в формате HTML")]
		public virtual bool IsBodyHtml { get; set; }

		/// <summary>
		/// Generates mail message subject and body from mail template.
		/// Substitutes all {name} with values from <paramref name="prms"/>.
		/// </summary>
		/// <param name="prms">Params object for substitution.</param>
		/// <returns>New mail message.</returns>
		[Obsolete("Use GenerateMailQueue to send messages using MailModule")]
		public virtual MailMessage GenerateMail(object prms)
		{
			Dictionary<string, object> dic = new Dictionary<string, object>();
			dic.Add(prms);
			return GenerateMail(dic);
		}

		/// <summary>
		/// Generates mail message subject and body from mail template.
		/// Substitutes all {name} with values from <paramref name="prms"/>.
		/// </summary>
		/// <param name="prms">Params dictionary for substitution.</param>
		/// <returns>New mail message.</returns>
		[Obsolete("Use GenerateMailQueue to send messages using MailModule")]
		public virtual MailMessage GenerateMail(Dictionary<string, object> prms)
		{
			MailMessage m = new MailMessage
			{
				Subject = ReplaceParams(Subject, prms),
				Body = ReplaceParams(Body, prms),
				IsBodyHtml = IsBodyHtml
			};
			return m;
		}

		/// <summary>
		/// Generates mail queue item with subject and body from mail template.
		/// Substitutes all {name} with values from <paramref name="prms"/>.
		/// </summary>
		/// <param name="toEmail">Recipient e-mail.</param>
		/// <param name="toName">Recipient name.</param>
		/// <param name="prms">Params object for substitution.</param>
		/// <returns>New mail message.</returns>
		public virtual MailQueue GenerateMailQueue(string toEmail, string toName, object prms)
		{
			Dictionary<string, object> dic = new Dictionary<string, object>();
			dic.Add(prms);
			return GenerateMailQueue(toEmail, toName, dic);
		}

		/// <summary>
		/// Generates mail queue item with subject and body from mail template.
		/// Substitutes all {name} with values from <paramref name="prms"/>.
		/// </summary>
		/// <param name="toEmail">Recipient e-mail.</param>
		/// <param name="toName">Recipient name.</param>
		/// <param name="prms">Params dictionary for substitution.</param>
		/// <returns>New mail message.</returns>
		public virtual MailQueue GenerateMailQueue(string toEmail, string toName, Dictionary<string, object> prms)
		{
			MailQueue m = new MailQueue
			{
				CreateDate = DateTime.UtcNow,
				ToEmail = toEmail,
				ToName = toName,
				Subject = ReplaceParams(Subject, prms),
				Body = ReplaceParams(Body, prms),
				IsBodyHtml = IsBodyHtml
			};
			return m;
		}

		/// <summary>
		/// Replaces dictionary params in input string.
		/// Params format is {name}.
		/// </summary>
		/// <param name="input">Input string.</param>
		/// <param name="prms">Params dictionary.</param>
		/// <returns>Replaces string.</returns>
		private string ReplaceParams(string input, Dictionary<string, object> prms)
		{
			// create regex
			string regexStr = @"\{[^}]+}";
			Regex regex = new Regex(regexStr, RegexOptions.IgnoreCase);

			// replace
			StringBuilder sb = new StringBuilder();
			MatchCollection matches = regex.Matches(input);

			int i = 0;
			foreach (Match m in matches)
			{
				// add middle text
				sb.Append(input.Substring(i, m.Index - i));

				// replace this item
				string name = m.Value.Substring(1, m.Value.Length - 2).ToLower();
				var kv = prms.FirstOrDefault(item => item.Key.ToLower() == name);
				if (!String.IsNullOrEmpty(kv.Key))
					sb.Append(kv.Value);
				else
					sb.Append(m.Value);

				i = m.Index + m.Length;
			}

			sb.Append(input.Substring(i));
			return sb.ToString();
		}
	}
}
